#define ModRM(mod,r,rm) (((mod&0x3)<<6)|(r&0x7)<<3|(rm&0x7))

#define R_AX 0
#define R_CX 1
#define R_DX 2
#define R_BX 3
#define R_SP 4
#define R_BP 5
#define R_SI 6
#define R_DI 7
#define R_R8 R_AX
#define R_R9 R_CX
#define R_R10 R_DX
#define R_R11 R_BX
#define R_R12 R_SP
#define R_R13 R_BP
#define R_R14 R_SI
#define R_R15 R_DI

#define MOD_RM 0 // [RAX]
#define MOD_RM_D8 1 // [RAX]+disp8
#define MOD_RM_D32 2 // [RAX]+disp32
#define MOD_R 3 // RAX

#define RM_AX R_AX // 0
#define RM_CX R_CX // 1
#define RM_DX R_DX // 2
#define RM_BX R_BX // 3
#define RM_SP R_SP // 4
#define RM_BP R_BP // 5
#define RM_SI R_SI // 6
#define RM_DI R_DI // 7

#define RM_R8 RM_AX
#define RM_R9 RM_CX
#define RM_R10 RM_DX
#define RM_R11 RM_BX
#define RM_R14 RM_SI
#define RM_R15 RM_DI

#define REX_NONE 0
#define REX_B 0x41
#define REX_R 0x44
#define REX_W 0x48
#define REX_WB 0x49
#define REX_WX 0x4A
#define REX_WXB 0x4B
#define REX_WR 0x4C
#define REX_WRB 0x4D
#define REX_WRX 0x4E
#define REX_WRXB 0x4F
#define REX_16 0x66 // 16位寻址模式
#define REX_NEW 0x40

/* 重要:采用intel格式 MR:从寄存器到内存(R/M, r), RM:从内存到寄存器(r, R/M) */
/* 后面只有ModR/M */
#define OP_MOV_MR 0x89
#define OP_MOV_RM 0x8B
#define OP_MOV_MR8 0x88
#define OP_MOV_RM8 0x8A
#define OP_MOVSX_RM8 0xBE // Need 0x0F prefix
#define OP_MOVSX_RM16 0xBF // Need 0x0F prefix
#define OP_MOVSX_RM 0x63
#define OP_CALL_M 0xFF // NOTE:寄存器CALL r=2
#define OP_ADD_MR 0x1
#define OP_SUB_MR 0x29
#define OP_CMP_MR 0x39
#define OP_CMP_MI8 0x80 // NOTE: r=7
#define OP_XOR_MR 0x31
#define OP_OR_MR 0x9
#define OP_AND_MR 0x21
#define OP_NOT_M 0xF7 // NOTE: r=2

/* 只有操作数,后面啥都没 */
#define OP_PUSH_AX 0x50
#define OP_PUSH_CX 0x51
#define OP_PUSH_DX 0x52
#define OP_PUSH_BX 0x53
#define OP_PUSH_SP 0x54
#define OP_PUSH_BP 0x55
#define OP_PUSH_SI 0x56
#define OP_PUSH_DI 0x57
#define OP_PUSH_R8  OP_PUSH_AX
#define OP_PUSH_R9  OP_PUSH_CX
#define OP_PUSH_R10 OP_PUSH_DX
#define OP_PUSH_R11 OP_PUSH_BX
#define OP_PUSH_R12 OP_PUSH_SP
#define OP_PUSH_R13 OP_PUSH_BP
#define OP_PUSH_R14 OP_PUSH_SI
#define OP_PUSH_R15 OP_PUSH_DI
#define OP_POP_AX 0x58
#define OP_POP_CX 0x59
#define OP_POP_DX 0x5A
#define OP_POP_BX 0x5B
#define OP_POP_SP 0x5C
#define OP_POP_BP 0x5D
#define OP_POP_SI 0x5E
#define OP_POP_DI 0x5F
#define OP_POP_R8  OP_POP_AX
#define OP_POP_R9  OP_POP_CX
#define OP_POP_R10 OP_POP_DX
#define OP_POP_R11 OP_POP_BX
#define OP_POP_R12 OP_POP_SP
#define OP_POP_R13 OP_POP_BP
#define OP_POP_R14 OP_POP_SI
#define OP_POP_R15 OP_POP_DI
#define OP_NOP 0x90
#define OP_RET 0xC3

/* 后面跟着立即数(可以是64位) */
#define OP_MOVABS 0xB8 // 默认rax
#define OP_MOV_MI 0xC7 // NOTE: r=0

/* 后面跟一个字节的相对偏移(有符号) */
#define OP_JB_REL8 0x72
#define OP_JS_REL8 0x78
#define OP_JL_REL8 0x7C
#define OP_J_REL8 0xEB

/* 立即数移位, ModR/M后跟一个字节 */
#define OP_SHL_MI8 0xC1 // NOTE: r=6
#define OP_SHR_MI8 0xC1 // NOTE: r=5
#define OP_SAR_MI8 0xC1 // NOTE: r=7

/* 寄存器移位, */
#define OP_SHL_MCL 0xD3 // NOTE: r=6
#define OP_SHR_MCL 0xD3 // NOTE: r=5
#define OP_SAR_MCL 0xD3 // NOTE: r=7

#define PREFIX 0x0F
/* 编译器用 */

union imm8 {
    uint8 num;
    char byte[1];
};

union imm16 {
    uint16 num;
    char byte[2];
};

union imm32 {
    uint32 num;
    char byte[4];
};

union imm64 {
    uint64 num;
    char byte[8];
};




